<template>
  <a-modal @cancel="close" title="上传LOGO" :width="445" title-align="start" size="small" :visible="visible" unmount-on-close>
    <a-spin :loading="spinning">
      <template #element>
        <icon-loading />
        <!-- 压缩进度 -->
        <div class="compress-tip"> 图片读取中 {{ readFilePercent }}% </div>
      </template>
      <div class="cropper-wrapper">
        <div class="cut-wrapper">
          <div class="cut">
            <vue-cropper
              ref="cropperRef"
              :info="true"
              :img="option.img"
              :output-size="option.size"
              :output-type="option.outputType"
              :full="option.full"
              :can-move="option.canMove"
              :can-move-box="option.canMoveBox"
              :fixed-box="option.fixedBox"
              :original="option.original"
              :auto-crop="option.autoCrop"
              :auto-crop-width="option.autoCropWidth"
              :auto-crop-height="option.autoCropHeight"
              :center-box="option.centerBox"
              :high="option.high"
              :max-img-size="option.max"
              @real-time="realTimeFn"
              @img-load="imgLoadFn"
              mode="cover"
            />
          </div>
          <div class="button-wrapper">
            <div class="btn-l">
              <label class="btn" for="uploads">{{ option.img ? '重新上传' : '上传图片' }}</label>
              <input
                type="file"
                id="uploads"
                style="position: absolute; clip: rect(0 0 0 0)"
                accept="image/png, image/jpeg, image/jpg"
                @change="uploadImgFn"
              />
            </div>
            <div class="btn-r">
              <icon-minus-circle @click="changeScaleFn(-1)" style="font-size: 20px; margin-right: 10px" />
              <icon-plus-circle @click="changeScaleFn(1)" style="font-size: 20px" />
            </div>
          </div>
        </div>
        <div class="model">
          <div class="model-show">
            <img :src="thumbSrc" alt="" v-if="thumbSrc" />
          </div>
          <span>头像预览</span>
        </div>
      </div>
    </a-spin>
    <template #footer>
      <a-button @click="close">关闭</a-button>
      <a-button type="primary" @click="saveFn">确认</a-button>
    </template>
  </a-modal>
</template>

<script setup name="EnterpriseLogoConfigModal">
  import { ref, reactive } from 'vue'
  import { VueCropper } from 'vue-cropper'
  import 'vue-cropper/dist/index.css'
  import { uploadImageBase64 } from '@/api/common/index'
  import { Message } from '@arco-design/web-vue'
  // 图片压缩
  import imageCompression from 'browser-image-compression'
  // emit 事件
  const emit = defineEmits(['ok'])
  // VueCropper 配置
  const option = reactive({
    img: '',
    size: 1,
    full: false,
    outputType: 'png',
    canMove: true,
    fixedBox: true,
    original: false,
    canMoveBox: true,
    autoCrop: true,
    // 只有自动截图开启 宽度高度才生效
    autoCropWidth: 104,
    autoCropHeight: 104,
    centerBox: true,
    high: true,
    max: 99999,
  })
  // 缩略图
  const thumbSrc = ref('')
  // 弹窗是否可见
  const visible = ref(false)
  // loading
  const spinning = ref(false)

  const cropperRef = ref()
  // 实时预览函数
  const realTimeFn = () => {
    cropperRef.value.getCropData((data) => {
      thumbSrc.value = data
    })
  }
  // 图片加载完成，关闭加载进度
  const imgLoadFn = () => {
    spinning.value = false
    readFilePercent.value = 0
  }
  // 缩放
  const changeScaleFn = (num) => {
    cropperRef.value.changeScale(num)
  }
  // 保存
  const saveFn = () => {
    if (!thumbSrc.value) {
      Message.warning('请上传企业LOGO后再进行保存')
      return false
    }
    spinning.value = true
    cropperRef.value.getCropData((data) => {
      if (data) {
        uploadImageBase64({ imageContent: data }).then((res) => {
          spinning.value = false
          if (res.code == 200) {
            close()
            emit('ok', res.result.fileIdStr)
          }
        })
      }
    })
  }
  // 选择文件
  // 读取文件进度
  const readFilePercent = ref(0)
  const uploadImgFn = (e) => {
    //上传图片
    var file = e.target.files[0]
    if (!/\.(jpg|jpeg|png)$/.test(e.target.value.toLowerCase())) {
      if (e.target.value) {
        Message.error('图片类型必须是jpeg,jpg,png,中的一种！')
      }
      return false
    }
    // 压缩图片
    const options = {
      maxSizeMB: 2, // 最大文件大小（MB）
      maxWidthOrHeight: 1920, // 最大宽度或高度（像素）
      initialQuality: 1, // 图片质量（0-1）
      useWebWorker: false, // 使用 Web Worker 进行非阻塞压缩，不建议开启，开启后会从 https://cdn.jsdelivr.net 拉取 worker 脚本，有时这个网站加载比较慢
      preserveExif: true, // 保留 EXIF 信息
      onProgress: (progress) => {
        console.log('压缩中...')
        if (progress > 99) progress = 99
        readFilePercent.value = progress
      },
    }
    // 压缩中
    spinning.value = true
    // 缩略图置空
    thumbSrc.value = ''
    imageCompression(file, options)
      .then((blob) => {
        // 压缩后的图片，更新到 vue-cropper
        option.img = window.URL.createObjectURL(blob)
      })
      .catch((error) => {
        console.error('压缩失败:', error)
        spinning.value = false
      })
  }
  // 修改
  const open = () => {
    visible.value = true
    option.img = ''
    thumbSrc.value = ''
  }
  // 关闭
  const close = () => {
    visible.value = false
    spinning.value = false
  }

  defineExpose({
    open,
  })
</script>
<style lang="less" scoped>
  .cropper-wrapper {
    display: flex;
    flex-direction: row;
    justify-content: center;
    align-items: flex-start;
    user-select: none;
    .cut-wrapper {
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      .cut {
        width: 270px;
        height: 270px;
      }

      .button-wrapper {
        display: flex;
        flex-wrap: wrap;
        align-content: center;
        justify-content: space-between;
        width: 100%;
        margin-top: 12px;

        .btn-l {
          color: #1890ff;
          font-size: 14px;
          font-weight: 500;
          line-height: 14px;
          .btn {
            cursor: pointer;
          }
        }
        .btn-r {
          cursor: pointer;
        }
      }
    }
    .model {
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      margin-left: 24px;
      .model-show {
        width: 101px;
        height: 101px;
        border-radius: 50%;
        overflow: hidden;
        margin-bottom: 12px;
        background: #f4f7f9;
        border: 1px solid #e7e7e7;
        img {
          width: 100%;
          height: 100%;
        }
      }
      span {
        font-size: 14px;
        font-weight: 400;
        color: #1f2334;
        line-height: 14px;
      }
    }
  }
  .compress-tip {
    margin-top: 6px;
    color: rgb(var(--primary-6));
    font-weight: 500;
    font-size: 14px;
  }
</style>
